using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Gko.Utils
{
	/// <summary>
	/// Extensions for <see cref="T:System.Collections.Generic.Queue`1"/>
	/// </summary>
	public static class QueueExtensions
	{
		/// <summary>
		/// Adds an object to the end of the <see cref="T:System.Collections.Generic.Queue`1"></see>.
		/// </summary>
		/// <typeparam name="TValue">The type of the value.</typeparam>
		/// <param name="queue">The queue.</param>
		/// <param name="items">
		/// The objects to add to the <see cref="T:System.Collections.Generic.Queue`1"></see>.
		/// </param>
		/// <exception cref="ArgumentNullException"><c>queue</c> or <c>items</c> is null.</exception>
		public static void Enqueue<TValue>(this Queue<TValue> queue, IEnumerable<TValue> items)
		{
			if (queue == null) {
				throw new ArgumentNullException("queue");
			}
			if (items == null) {
				throw new ArgumentNullException("items");
			}

			foreach (var item in items) {
				queue.Enqueue(item);
			}
		}

		/// <summary>
		/// Removes and returns the object at the beginning of the <see cref="T:System.Collections.Generic.Queue`1"></see>.
		/// </summary>
		/// <typeparam name="TValue">The type of the value.</typeparam>
		/// <param name="queue">The queue.</param>
		/// <param name="count">The count of items to dequeue.</param>
		/// <returns>Values from queue</returns>
		/// <exception cref="ArgumentNullException"><c>queue</c> is null.</exception>
		public static IEnumerable<TValue> Dequeue<TValue>(this Queue<TValue> queue, int count)
		{
			if (queue == null) {
				throw new ArgumentNullException("queue");
			}
			for (var i = 0; i < count && queue.Count > 0; i++) {
				yield return queue.Dequeue();
			}
		}

		/// <summary>
		/// Returns the object at the beginning of the <see cref="T:System.Collections.Generic.Queue`1"></see> without removing it.
		/// </summary>
		/// <typeparam name="TValue">The type of the value.</typeparam>
		/// <param name="queue">The queue.</param>
		/// <param name="count">The count of items to peek.</param>
		/// <returns>Values from queue</returns>
		/// <exception cref="ArgumentNullException"><c>queue</c> is null.</exception>
		public static IEnumerable<TValue> Peek<TValue>(this Queue<TValue> queue, int count)
		{
			if (queue == null) {
				throw new ArgumentNullException("queue");
			}
			return queue.Take(count);
		}
	}
}